﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PauseScreen.cs" company="">
//   
// </copyright>
// <summary>
//   The pause screen.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

/*
 * Author: Mikkel Thordal Andersen
 * Created: 7-12-2011
 */
namespace ITU_vs_Zombies.Menu.Screens
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;

    using ITU_vs_Zombies.Game;
    using ITU_vs_Zombies.Scenery;

    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Content;
    using Microsoft.Xna.Framework.GamerServices;
    using Microsoft.Xna.Framework.Media;
    using Microsoft.Xna.Framework.Storage;

    /// <summary>
    /// The pause screen.
    /// </summary>
    public class PauseScreen : MenuScreen
    {
        #region Constants and Fields

        /// <summary>
        /// The gameplay screen.
        /// </summary>
        private readonly GameplayScreen gameplayScreen;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="PauseScreen"/> class.
        /// </summary>
        /// <param name="gameplayScreen">
        /// The gameplay screen.
        /// </param>
        public PauseScreen(GameplayScreen gameplayScreen)
            : base("Pause Menu")
        {
            this.gameplayScreen = gameplayScreen;

            var resumeEntry = new MenuEntry("Resume");
            var saveGameEntry = new MenuEntry("Save");
            var mainMenuEntry = new MenuEntry("Main Menu");
            var exitMenuEntry = new MenuEntry("Exit");

            resumeEntry.Selected += this.ResumeGameMenuEntrySelected;
            saveGameEntry.Selected += this.SaveGameMenuEntrySelected;
            mainMenuEntry.Selected += this.MainMenuMenuEntrySelected;
            exitMenuEntry.Selected += this.OnCancel;

            this.MenuEntries.Add(resumeEntry);
            this.MenuEntries.Add(saveGameEntry);
            this.MenuEntries.Add(mainMenuEntry);
            this.MenuEntries.Add(exitMenuEntry);
            this.SongName = @"Sounds\MenuSound";
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// The activate.
        /// </summary>
        /// <param name="instancePreserved">
        /// The instance preserved.
        /// </param>
        public override void Activate(bool instancePreserved)
        {
            var content = new ContentManager(this.ScreenManager.Game.Services, "Content");
            this.Song = content.Load<Song>(this.SongName);
        }

        /// <summary>
        /// The save to device.
        /// </summary>
        /// <param name="result">
        /// The result.
        /// </param>
        public void SaveToDevice(IAsyncResult result)
        {
            Client.Device = StorageDevice.EndShowSelector(result);
            if (Client.Device != null && Client.Device.IsConnected)
            {
                SaveGame saveData = new SaveGame()
                                        {
                                            Player = Client.MainPlayer,
                                            Floors = new List<Floor>(),
                                        };

                foreach (Floor floor in Client.Floors)
                {
                    saveData.Floors.Add(floor);
                }

                IAsyncResult r = Client.Device.BeginOpenContainer(Client.ContainerName, null, null);
                result.AsyncWaitHandle.WaitOne();
                StorageContainer container = Client.Device.EndOpenContainer(r);
                if (container.FileExists(Client.Filename))
                {
                    container.DeleteFile(Client.Filename);
                }

                Stream stream = container.CreateFile(Client.Filename);
                var formatter = new BinaryFormatter();
                try
                {
                    formatter.Serialize(stream, saveData);
                }
                catch (SerializationException e)
                {

                    throw;
                }
                finally
                {
                    stream.Close();
                    container.Dispose();
                    result.AsyncWaitHandle.Close();
                }
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// The on cancel.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="o">
        /// The o.
        /// </param>
        protected override void OnCancel(object sender, object o)
        {
            this.ScreenManager.Game.Exit();
        }

        /// <summary>
        /// The initiate save.
        /// </summary>
        private void InitiateSave()
        {
            if (!Guide.IsVisible)
            {
                Client.Device = null;
                StorageDevice.BeginShowSelector(PlayerIndex.One, this.SaveToDevice, null);
            }
        }

        /// <summary>
        /// The main menu menu entry selected.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void MainMenuMenuEntrySelected(object sender, EventArgs e)
        {
            this.ExitScreen();
            this.gameplayScreen.ExitScreen();
            Client.StoreScore();
            Client.Dispose();
            Client.MainPlayer = null;
        }

        /// <summary>
        /// The resume game menu entry selected.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void ResumeGameMenuEntrySelected(object sender, EventArgs e)
        {
            this.ScreenManager.StopMusic();
            Client.GameState = GameStateEnum.Normal;
            this.ExitScreen();
        }

        /// <summary>
        /// The save game menu entry selected.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void SaveGameMenuEntrySelected(object sender, EventArgs e)
        {
            this.InitiateSave();
        }

        #endregion
    }
}